package com.imagecollector.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.imagecollector.common.constant.TaskConstant;
import com.imagecollector.domain.dto.TaskAuditFailDTO;
import com.imagecollector.domain.dto.TaskAuditPassDTO;
import com.imagecollector.domain.dto.TaskAuditSearchDTO;
import com.imagecollector.domain.entity.*;
import com.imagecollector.domain.vo.AuditInfoVO;
import com.imagecollector.mapper.TaskAuditRecordMapper;
import com.imagecollector.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 任务审核记录表 服务实现类
 * </p>
 *
 * @author wrf
 * @since 2024-07-31
 */
@Service
public class TaskAuditRecordServiceImpl extends ServiceImpl<TaskAuditRecordMapper, TaskAuditRecord> implements ITaskAuditRecordService {

    @Autowired
    private ITaskSubmitRecordService taskSubmitRecordService;

    @Autowired
    @Lazy
    private ITaskService taskService;

    @Autowired
    private IPictureService pictureService;

    @Autowired
    @Lazy
    private ITaskReceiverRecordService taskReceiverRecordService;

    /**
     * 审核任务通过
     * 该方法负责记录任务审核通过的状态，并更新相关记录，包括任务提交记录、任务状态以及图片信息
     * 使用了@Transactional注解，确保所有数据库操作要么全部完成，要么全部不完成
     *
     * @param taskAuditPassDTO 包含任务审核所需信息的数据传输对象
     * @return 审核操作是否成功
     */
    @Override
    @Transactional
    public boolean auditPass(TaskAuditPassDTO taskAuditPassDTO) {

        TaskAuditRecord taskAuditRecord = getAuditRecord(taskAuditPassDTO.getTaskId(), taskAuditPassDTO.getUserId(), taskAuditPassDTO.getSubmitRecordId());
        if (Objects.nonNull(taskAuditRecord)) {
            // 已审核过再次审核
            taskAuditRecord.setStatus(TaskConstant.TASK_STATUS_APPROVED);
            updateById(taskAuditRecord);
        } else {
            // 首次审核 保存任务审核记录
            save(new TaskAuditRecord()
                    .setTaskId(taskAuditPassDTO.getTaskId())
                    .setUserId(taskAuditPassDTO.getUserId())
                    .setAuditUserId(taskAuditPassDTO.getAuditUserId())
                    .setStatus(TaskConstant.TASK_STATUS_APPROVED));
        }
        // 获取任务提交记录并更新其状态为审核通过
        TaskSubmitRecord taskSubmitRecord = taskSubmitRecordService.getById(taskAuditPassDTO.getSubmitRecordId());
        Objects.requireNonNull(taskSubmitRecord, "用户提交记录不存在");
        taskSubmitRecord.setStatus(TaskConstant.TASK_STATUS_APPROVED);
        taskSubmitRecordService.updateById(taskSubmitRecord);

        // 如果该任务不是群发任务,获取任务信息并更新其状态为审核通过
        Task task = taskService.getById(taskAuditPassDTO.getTaskId());
        Objects.requireNonNull(task, "任务已不存在");
        if (task.getIsRepeatedlyReceive() == 0) {
            task.setStatus(TaskConstant.TASK_STATUS_APPROVED);
            taskService.updateById(task);
        }

        // 更新图片信息，设置客服相关信息
        Picture picture = pictureService.getPicture(taskAuditPassDTO.getTaskId(), taskAuditPassDTO.getUserId(), taskAuditPassDTO.getSubmitRecordId());
        Objects.requireNonNull(picture, "图片信息不存在");
        picture.setCustomerServiceId(taskAuditPassDTO.getAuditUserId());
        picture.setCustomerServiceIsRemark(1);
        picture.setCustomerServiceRemarkScenic(taskAuditPassDTO.getCustomerServiceRemarkScenic());
        picture.setCustomerServiceRemarkExhibits(taskAuditPassDTO.getCustomerServiceRemarkExhibits());
        pictureService.updateById(picture);

        return true;
    }

    public TaskAuditRecord getAuditRecord(Integer taskId, Integer userId, Integer submitRecordId) {
        return lambdaQuery().eq(TaskAuditRecord::getTaskId, taskId)
                .eq(TaskAuditRecord::getUserId, userId)
                .eq(TaskAuditRecord::getSubmitRecordId, submitRecordId)
                .one();
    }

    /**
     * 任务审核不通过处理方法
     *
     * @param taskAuditFailDTO 包含任务审核失败的相关信息，如任务ID、用户ID、提交记录ID、审核员ID和备注
     * @return 操作是否成功，目前此方法始终返回true，表示操作成功
     */
    @Override
    public boolean auditFail(TaskAuditFailDTO taskAuditFailDTO) {
        // 根据任务ID、用户ID和提交记录ID获取现有的审核记录
        TaskAuditRecord taskAuditRecord = getAuditRecord(taskAuditFailDTO.getTaskId(), taskAuditFailDTO.getUserId(), taskAuditFailDTO.getSubmitRecordId());
        if (Objects.nonNull(taskAuditRecord)) {
            // 如果已有审核记录，则更新审核记录的审核人、状态和备注
            taskAuditRecord.setAuditUserId(taskAuditFailDTO.getAuditUserId());
            taskAuditRecord.setStatus(TaskConstant.TASK_STATUS_REJECTED);
            taskAuditRecord.setRemark(taskAuditFailDTO.getRemark());
            // 更新审核记录
            updateById(taskAuditRecord);
        } else {
            // 如果没有审核记录，则新建审核记录并设置相关信息
            save(new TaskAuditRecord()
                    .setTaskId(taskAuditFailDTO.getTaskId())
                    .setUserId(taskAuditFailDTO.getUserId())
                    .setAuditUserId(taskAuditFailDTO.getAuditUserId())
                    .setStatus(TaskConstant.TASK_STATUS_REJECTED)
                    .setSubmitRecordId(taskAuditFailDTO.getSubmitRecordId())
                    .setRemark(taskAuditFailDTO.getRemark()));
        }
        // 获取用户提交记录并更新其状态为审核不通过
        TaskSubmitRecord taskSubmitRecord = taskSubmitRecordService.getById(taskAuditFailDTO.getSubmitRecordId());
        Objects.requireNonNull(taskSubmitRecord, "用户提交记录不存在");
        taskSubmitRecord.setStatus(TaskConstant.TASK_STATUS_REJECTED);
        taskSubmitRecordService.updateById(taskSubmitRecord);

        // 修改用户接收记录表为已接取未完成状态
        TaskReceiverRecord taskReceiverRecord = taskReceiverRecordService.getById(taskSubmitRecord.getReceiverRecordId());
        taskReceiverRecord.setStatus(TaskConstant.TASK_STATUS_RECEIVED);
        taskReceiverRecordService.updateById(taskReceiverRecord);

        // 如果该任务不是群发任务,获取任务信息并更新其状态为审核不通过
        Task task = taskService.getById(taskAuditFailDTO.getTaskId());
        Objects.requireNonNull(task, "任务已不存在");
        if (task.getIsRepeatedlyReceive() == 0) {
            task.setStatus(TaskConstant.TASK_STATUS_REJECTED);
            taskService.updateById(task);
        }

        return true;
    }

    @Override
    public AuditInfoVO getAuditRecordById(Integer auditRecordId) {
        TaskAuditRecord auditRecord = lambdaQuery().eq(TaskAuditRecord::getId, auditRecordId).one();
        if (Objects.isNull(auditRecord)) {
            return null;
        }
        return new AuditInfoVO()
                .setUserId(auditRecord.getUserId())
                .setUpdateTime(auditRecord.getUpdateTime())
                .setAuditUserId(auditRecord.getAuditUserId())
                .setCreateTime(auditRecord.getCreateTime())
                .setId(auditRecord.getId())
                .setRemark(auditRecord.getRemark())
                .setStatus(auditRecord.getStatus())
                .setSubmitRecordId(auditRecord.getSubmitRecordId())
                .setTaskId(auditRecord.getTaskId());
    }

    @Override
    public Page<AuditInfoVO> auditList(TaskAuditSearchDTO taskAuditSearchDTO) {
        LambdaQueryWrapper<TaskAuditRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Objects.nonNull(taskAuditSearchDTO.getTaskId()), TaskAuditRecord::getTaskId, taskAuditSearchDTO.getTaskId())
                .eq(Objects.nonNull(taskAuditSearchDTO.getUserId()), TaskAuditRecord::getUserId, taskAuditSearchDTO.getUserId())
                .eq(Objects.nonNull(taskAuditSearchDTO.getStatus()), TaskAuditRecord::getStatus, taskAuditSearchDTO.getStatus())
                .eq(Objects.nonNull(taskAuditSearchDTO.getAuditUserId()), TaskAuditRecord::getAuditUserId, taskAuditSearchDTO.getAuditUserId());
        Page<TaskAuditRecord> auditRecordPage = page(new Page<>(taskAuditSearchDTO.getPageNo(), taskAuditSearchDTO.getPageSize()), queryWrapper);
        Page<AuditInfoVO> auditInfoVOPage = new Page<>();
        if (CollectionUtil.isNotEmpty(auditRecordPage.getRecords())){
            auditInfoVOPage.setCurrent(auditRecordPage.getCurrent());
            auditInfoVOPage.setSize(auditRecordPage.getSize());
            auditInfoVOPage.setTotal(auditRecordPage.getTotal());
            auditInfoVOPage.setRecords(auditRecordPage.getRecords().stream().map(auditRecord -> new AuditInfoVO()
                    .setUserId(auditRecord.getUserId())
                    .setUpdateTime(auditRecord.getUpdateTime())
                    .setAuditUserId(auditRecord.getAuditUserId())
                    .setCreateTime(auditRecord.getCreateTime())
                    .setId(auditRecord.getId())
                    .setRemark(auditRecord.getRemark())
                    .setStatus(auditRecord.getStatus())
                    .setSubmitRecordId(auditRecord.getSubmitRecordId())
                    .setTaskId(auditRecord.getTaskId())
            ).collect(Collectors.toList()));
        }
        return auditInfoVOPage;
    }
}
